{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "<a href=\"https://colab.research.google.com/drive/1Gf_1mipiJe09PjiweSFBDi9cEMPkbS5N?usp=sharing\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"></a>"
      ],
      "metadata": {
        "id": "9qAE-y8REYbS"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "### Reflexion Agentic Pattern\n",
        "\n",
        "A self-improving agent that learns from execution feedback through:\n",
        "- Action: Execute real tasks\n",
        "- Evaluation: Observe actual outcomes\n",
        "- Reflection: Analyze failures and successes\n",
        "- Memory: Store insights for future attempts\n",
        "- Retry: Improve using past reflections\n"
      ],
      "metadata": {
        "id": "JOS4xiKnTsC0"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "7p71IqR50aHM"
      },
      "outputs": [],
      "source": [
        "!pip install -qU google-generativeai"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import google.generativeai as genai\n",
        "import getpass\n",
        "from datetime import datetime"
      ],
      "metadata": {
        "id": "x6aMLxd6T-Ob"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Get Google's Gemini API Key here: https://aistudio.google.com/app/apikey"
      ],
      "metadata": {
        "id": "JcCCZzhjX7vR"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "API_KEY = getpass.getpass(\"Enter your Google API key: \")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "BeKVKC-GUBYj",
        "outputId": "4162ffb3-8a07-4e62-e457-e74df4f29465"
      },
      "execution_count": null,
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Enter your Google AI API key: ··········\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "# Configure API\n",
        "genai.configure(api_key=API_KEY)"
      ],
      "metadata": {
        "id": "1JONr7RtUIaS"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "class ReflexionAgent:\n",
        "    def __init__(self):\n",
        "        self.model = genai.GenerativeModel(\"gemini-2.0-flash\")\n",
        "        self.tools = {}\n",
        "        self.episodic_memory = []  # Stores past attempts and reflections\n",
        "\n",
        "    def add_tool(self, name, func, description):\n",
        "        self.tools[name] = {\"func\": func, \"desc\": description}\n",
        "\n",
        "    def execute_action(self, tool_name, params):\n",
        "        \"\"\"Execute a tool and return result with success status\"\"\"\n",
        "        try:\n",
        "            if tool_name not in self.tools:\n",
        "                return {\"success\": False, \"result\": f\"Tool {tool_name} not found\", \"error\": \"Invalid tool\"}\n",
        "\n",
        "            result = self.tools[tool_name][\"func\"](**params)\n",
        "            return {\"success\": True, \"result\": result, \"error\": None}\n",
        "        except Exception as e:\n",
        "            return {\"success\": False, \"result\": None, \"error\": str(e)}\n",
        "\n",
        "    def evaluate_outcome(self, task, action, outcome):\n",
        "        \"\"\"Evaluate if the action succeeded and why\"\"\"\n",
        "        prompt = f\"\"\"Evaluate this task execution:\n",
        "\n",
        "Task: {task}\n",
        "Action Taken: {action}\n",
        "Outcome: {outcome}\n",
        "\n",
        "Analyze:\n",
        "1. Did it succeed? (Yes/No)\n",
        "2. If failed, what went wrong?\n",
        "3. If succeeded, what worked well?\n",
        "\n",
        "Provide a brief evaluation (2-3 sentences):\"\"\"\n",
        "\n",
        "        response = self.model.generate_content(prompt).text\n",
        "        return response.strip()\n",
        "\n",
        "    def reflect(self, task, action, outcome, evaluation):\n",
        "        \"\"\"Generate verbal reflection on what to improve\"\"\"\n",
        "        prompt = f\"\"\"Reflect on this experience to learn and improve:\n",
        "\n",
        "Task: {task}\n",
        "Action: {action}\n",
        "Outcome: {outcome}\n",
        "Evaluation: {evaluation}\n",
        "\n",
        "Reflection (answer these):\n",
        "1. What should be done differently next time?\n",
        "2. What specific mistakes to avoid?\n",
        "3. What strategy would work better?\n",
        "\n",
        "Provide actionable insights:\"\"\"\n",
        "\n",
        "        response = self.model.generate_content(prompt).text\n",
        "        return response.strip()\n",
        "\n",
        "    def retrieve_relevant_memory(self, task):\n",
        "        \"\"\"Get past reflections related to current task\"\"\"\n",
        "        if not self.episodic_memory:\n",
        "            return \"No past experience with similar tasks.\"\n",
        "\n",
        "        # Simple relevance matching\n",
        "        relevant = []\n",
        "        for memory in self.episodic_memory:\n",
        "            if any(word in memory[\"task\"].lower() for word in task.lower().split()):\n",
        "                relevant.append(memory)\n",
        "\n",
        "        if not relevant:\n",
        "            return \"No directly relevant past experience.\"\n",
        "\n",
        "        # Return most recent relevant memories\n",
        "        memory_text = \"\\n\\n\".join([\n",
        "            f\"Past Attempt:\\nTask: {m['task']}\\nWhat Failed: {m['outcome']}\\nLesson Learned: {m['reflection']}\"\n",
        "            for m in relevant[-3:]  # Last 3 relevant memories\n",
        "        ])\n",
        "        return memory_text\n",
        "\n",
        "    def plan_action(self, task, past_memories):\n",
        "        \"\"\"Plan action using past reflections\"\"\"\n",
        "        tools_desc = \"\\n\".join([f\"- {n}: {t['desc']}\" for n, t in self.tools.items()])\n",
        "\n",
        "        prompt = f\"\"\"You are a Reflexion agent that learns from experience.\n",
        "\n",
        "Task: {task}\n",
        "\n",
        "Available Tools:\n",
        "{tools_desc}\n",
        "\n",
        "Past Experience:\n",
        "{past_memories}\n",
        "\n",
        "Based on past failures and lessons, plan your action.\n",
        "Respond in this format:\n",
        "Tool: tool_name\n",
        "Params: {{\"param1\": \"value1\", \"param2\": \"value2\"}}\n",
        "Reasoning: Why this approach will work\n",
        "\n",
        "Response:\"\"\"\n",
        "\n",
        "        response = self.model.generate_content(prompt).text\n",
        "        return response\n",
        "\n",
        "    def run(self, task, max_attempts=3):\n",
        "        \"\"\"Run task with reflexion loop\"\"\"\n",
        "        print(f\"\\n🎯 Task: {task}\\n\")\n",
        "\n",
        "        for attempt in range(1, max_attempts + 1):\n",
        "            print(f\"{'='*60}\")\n",
        "            print(f\"ATTEMPT {attempt}/{max_attempts}\")\n",
        "            print(f\"{'='*60}\\n\")\n",
        "\n",
        "            # Step 1: Retrieve relevant memories\n",
        "            past_memories = self.retrieve_relevant_memory(task)\n",
        "            print(f\"📚 Consulting Memory:\\n{past_memories}\\n\")\n",
        "\n",
        "            # Step 2: Plan action based on memories\n",
        "            plan = self.plan_action(task, past_memories)\n",
        "            print(f\"🧠 Plan:\\n{plan}\\n\")\n",
        "\n",
        "            # Parse plan to extract tool and params\n",
        "            tool_name = None\n",
        "            params = {}\n",
        "\n",
        "            for line in plan.split(\"\\n\"):\n",
        "                if line.startswith(\"Tool:\"):\n",
        "                    tool_name = line.split(\"Tool:\")[-1].strip()\n",
        "                elif line.startswith(\"Params:\"):\n",
        "                    try:\n",
        "                        params_str = line.split(\"Params:\")[-1].strip()\n",
        "                        params = eval(params_str)\n",
        "                    except:\n",
        "                        params = {}\n",
        "\n",
        "            if not tool_name:\n",
        "                print(\"❌ Could not parse action plan\\n\")\n",
        "                continue\n",
        "\n",
        "            # Step 3: Execute action\n",
        "            print(f\"⚡ Executing: {tool_name} with {params}\")\n",
        "            outcome = self.execute_action(tool_name, params)\n",
        "            print(f\"📊 Outcome: {outcome}\\n\")\n",
        "\n",
        "            # Step 4: Evaluate the outcome\n",
        "            evaluation = self.evaluate_outcome(task, f\"{tool_name}({params})\", outcome)\n",
        "            print(f\"🔍 Evaluation:\\n{evaluation}\\n\")\n",
        "\n",
        "            # Step 5: Check if successful\n",
        "            if outcome[\"success\"] and \"yes\" in evaluation.lower():\n",
        "                print(f\"✅ SUCCESS! Task completed.\\n\")\n",
        "                print(f\"Final Result: {outcome['result']}\\n\")\n",
        "\n",
        "                # Store successful experience\n",
        "                self.episodic_memory.append({\n",
        "                    \"task\": task,\n",
        "                    \"attempt\": attempt,\n",
        "                    \"action\": f\"{tool_name}({params})\",\n",
        "                    \"outcome\": outcome[\"result\"],\n",
        "                    \"evaluation\": evaluation,\n",
        "                    \"reflection\": \"Success - approach worked well\",\n",
        "                    \"timestamp\": datetime.now().isoformat()\n",
        "                })\n",
        "\n",
        "                return outcome[\"result\"]\n",
        "\n",
        "            # Step 6: Reflect on failure\n",
        "            reflection = self.reflect(task, f\"{tool_name}({params})\", outcome, evaluation)\n",
        "            print(f\"💭 Reflection:\\n{reflection}\\n\")\n",
        "\n",
        "            # Step 7: Store in episodic memory\n",
        "            self.episodic_memory.append({\n",
        "                \"task\": task,\n",
        "                \"attempt\": attempt,\n",
        "                \"action\": f\"{tool_name}({params})\",\n",
        "                \"outcome\": outcome,\n",
        "                \"evaluation\": evaluation,\n",
        "                \"reflection\": reflection,\n",
        "                \"timestamp\": datetime.now().isoformat()\n",
        "            })\n",
        "\n",
        "            print(f\"💾 Stored reflection in memory for next attempt\\n\")\n",
        "\n",
        "        print(f\"❌ Task failed after {max_attempts} attempts\\n\")\n",
        "        return \"Task not completed successfully\""
      ],
      "metadata": {
        "id": "rt_wIa8rUK5V"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Define tools with realistic success/failure scenarios\n",
        "def run_code(code):\n",
        "    \"\"\"Execute Python code - can fail with errors\"\"\"\n",
        "    try:\n",
        "        # Simulate code execution with potential errors\n",
        "        if \"divide\" in code.lower() and \"0\" in code:\n",
        "            raise ZeroDivisionError(\"Cannot divide by zero\")\n",
        "        if \"import unknown\" in code.lower():\n",
        "            raise ImportError(\"Module 'unknown' not found\")\n",
        "\n",
        "        # Simple eval for demo\n",
        "        result = eval(code)\n",
        "        return f\"Code executed successfully. Result: {result}\"\n",
        "    except Exception as e:\n",
        "        return f\"Error: {type(e).__name__}: {str(e)}\"\n",
        "\n",
        "def api_call(endpoint):\n",
        "    \"\"\"Simulate API call - can fail or return errors\"\"\"\n",
        "    apis = {\n",
        "        \"user\": {\"status\": 200, \"data\": \"User data retrieved\"},\n",
        "        \"posts\": {\"status\": 200, \"data\": \"Posts list retrieved\"},\n",
        "        \"invalid\": {\"status\": 404, \"data\": \"Endpoint not found\"},\n",
        "    }\n",
        "\n",
        "    result = apis.get(endpoint, {\"status\": 500, \"data\": \"Server error\"})\n",
        "\n",
        "    if result[\"status\"] != 200:\n",
        "        raise Exception(f\"API Error {result['status']}: {result['data']}\")\n",
        "\n",
        "    return result[\"data\"]\n",
        "\n",
        "def search_docs(query):\n",
        "    \"\"\"Search documentation - may return incomplete results\"\"\"\n",
        "    docs = {\n",
        "        \"python list\": \"Lists are mutable sequences. Use append() to add items.\",\n",
        "        \"error handling\": \"Use try-except blocks to handle exceptions.\",\n",
        "        \"api\": \"APIs allow communication between applications.\",\n",
        "    }\n",
        "\n",
        "    for key, val in docs.items():\n",
        "        if key in query.lower():\n",
        "            return val\n",
        "\n",
        "    return f\"No documentation found for: {query}\""
      ],
      "metadata": {
        "id": "LehdszfjUR4b"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Usage Examples\n",
        "print(\"=\"*60)\n",
        "print(\"REFLEXION AGENT DEMO\")\n",
        "print(\"=\"*60)\n",
        "\n",
        "agent = ReflexionAgent()\n",
        "\n",
        "# Add tools\n",
        "agent.add_tool(\"run_code\", run_code, \"Execute Python code\")\n",
        "agent.add_tool(\"api_call\", api_call, \"Make API request to endpoint\")\n",
        "agent.add_tool(\"search_docs\", search_docs, \"Search documentation\")\n",
        "\n",
        "# Example 1: Code execution that might fail initially\n",
        "print(\"\\n\" + \"=\"*60)\n",
        "print(\"EXAMPLE 1: Code Execution with Error Recovery\")\n",
        "print(\"=\"*60)\n",
        "result = agent.run(\"Calculate the result of 100 divided by 5\")\n",
        "\n",
        "# Example 2: API call that needs correction\n",
        "print(\"\\n\" + \"=\"*60)\n",
        "print(\"EXAMPLE 2: API Call with Endpoint Correction\")\n",
        "print(\"=\"*60)\n",
        "result = agent.run(\"Get user information from the API\")\n",
        "\n",
        "# Show learned memories\n",
        "print(\"\\n\" + \"=\"*60)\n",
        "print(\"EPISODIC MEMORY (What the agent learned)\")\n",
        "print(\"=\"*60)\n",
        "for i, memory in enumerate(agent.episodic_memory, 1):\n",
        "    print(f\"\\nMemory {i}:\")\n",
        "    print(f\"Task: {memory['task']}\")\n",
        "    print(f\"Attempt: {memory['attempt']}\")\n",
        "    print(f\"Reflection: {memory['reflection'][:100]}...\")"
      ],
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "id": "jB4jAf3NUVlY",
        "outputId": "3215d07e-80ca-4659-bafa-34ff46970002"
      },
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "============================================================\n",
            "REFLEXION AGENT DEMO\n",
            "============================================================\n",
            "\n",
            "============================================================\n",
            "EXAMPLE 1: Code Execution with Error Recovery\n",
            "============================================================\n",
            "\n",
            "🎯 Task: Calculate the result of 100 divided by 5\n",
            "\n",
            "============================================================\n",
            "ATTEMPT 1/3\n",
            "============================================================\n",
            "\n",
            "📚 Consulting Memory:\n",
            "No past experience with similar tasks.\n",
            "\n",
            "🧠 Plan:\n",
            "Tool: run_code\n",
            "Params: {\"code\": \"print(100 / 5)\"}\n",
            "Reasoning: I can use the run_code tool to execute a simple Python expression that performs the division. This is a straightforward calculation and should be accurate.\n",
            "\n",
            "\n",
            "⚡ Executing: run_code with {'code': 'print(100 / 5)'}\n",
            "20.0\n",
            "📊 Outcome: {'success': True, 'result': 'Code executed successfully. Result: None', 'error': None}\n",
            "\n",
            "🔍 Evaluation:\n",
            "1. Yes\n",
            "2. N/A\n",
            "3. The code executed successfully and performed the division as requested. However, the 'result' is None, indicating that the code printed the output to standard output but did not return a value that was captured by the execution environment.\n",
            "\n",
            "Evaluation: The task was successfully executed in the sense that the calculation was likely performed and printed. Ideally, the code should have returned the result rather than just printing it for better task management.\n",
            "\n",
            "✅ SUCCESS! Task completed.\n",
            "\n",
            "Final Result: Code executed successfully. Result: None\n",
            "\n",
            "\n",
            "============================================================\n",
            "EXAMPLE 2: API Call with Endpoint Correction\n",
            "============================================================\n",
            "\n",
            "🎯 Task: Get user information from the API\n",
            "\n",
            "============================================================\n",
            "ATTEMPT 1/3\n",
            "============================================================\n",
            "\n",
            "📚 Consulting Memory:\n",
            "Past Attempt:\n",
            "Task: Calculate the result of 100 divided by 5\n",
            "What Failed: Code executed successfully. Result: None\n",
            "Lesson Learned: Success - approach worked well\n",
            "\n",
            "🧠 Plan:\n",
            "Tool: search_docs\n",
            "Params: {\"query\": \"get user information\"}\n",
            "Reasoning: I need to understand how to use the API to get user information. Searching the documentation is the first step to understanding the available endpoints and required parameters.\n",
            "\n",
            "\n",
            "⚡ Executing: search_docs with {'query': 'get user information'}\n",
            "📊 Outcome: {'success': True, 'result': 'No documentation found for: get user information', 'error': None}\n",
            "\n",
            "🔍 Evaluation:\n",
            "1. No\n",
            "2. The search query \"get user information\" did not find any relevant documentation. This suggests either the query was too broad, the documentation is poorly organized, or the documentation for that specific function is missing.\n",
            "3. N/A\n",
            "\n",
            "Evaluation: The task failed because the search query was unsuccessful in finding relevant documentation. A more targeted search query or a review of the available documentation structure is needed.\n",
            "\n",
            "💭 Reflection:\n",
            "Okay, let's break down how to improve this process based on the evaluation.\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  **What should be done differently next time?**\n",
            "\n",
            "*   **Refine the Search Query:** Instead of a broad \"get user information,\" try to be more specific based on what I *know* about the API. Does it have user IDs, usernames, email addresses? Try searches like:\n",
            "    *   `get user by ID`\n",
            "    *   `retrieve user profile`\n",
            "    *   `fetch user data`\n",
            "    *   `user authentication` (if it's about logging in or accessing user data)\n",
            "    *   `search user`\n",
            "\n",
            "*   **Check the API's Naming Conventions:** Is there a standard way the API names its functions and parameters related to users? If I've seen examples of other API calls, mimic that style. For example, if other functions use the prefix \"fetch,\" try \"fetch user.\"\n",
            "\n",
            "*   **Consider API Version:** If the API has versions, make sure I'm searching documentation for the correct version. Some functions might have changed or been deprecated.\n",
            "\n",
            "*   **Explore API Documentation Directly:** Before even using `search_docs`, if possible, explore a general documentation index or table of contents. This can give a sense of the overall structure and naming conventions used within the documentation.\n",
            "\n",
            "2.  **What specific mistakes to avoid?**\n",
            "\n",
            "*   **Using overly general queries:** Avoid phrasing questions in very broad terms that could relate to a wide range of concepts.\n",
            "*   **Assuming the documentation will use plain English:** API documentation is often quite technical and uses specific terminology.\n",
            "\n",
            "3.  **What strategy would work better?**\n",
            "\n",
            "*   **Iterative Search:** Start with a slightly more specific query than the original, and then refine further based on the results (or lack thereof). If the first refined search fails, try another refinement in a different direction.\n",
            "*   **Keyword Combination:** Combine keywords related to the action (e.g., \"get,\" \"retrieve,\" \"fetch\") with keywords related to the data (e.g., \"user,\" \"profile,\" \"account\").\n",
            "*   **Break Down the Goal:** If \"get user information\" is too broad, break it down into smaller pieces. E.g., first find documentation on *authenticating* a user, then documentation on *retrieving* their details.\n",
            "*   **Examine Successful Calls (If Available):** If other API calls have worked, look at the code or documentation related to those calls.  This might give clues as to how to structure the search for user information.\n",
            "*   **Look for Related Concepts:** If I can't find \"user information\" directly, search for related concepts, like \"authentication,\" \"authorization,\" \"profile,\" \"account.\"  The documentation for these might contain hints or links to the user information functions.\n",
            "*   **Document Inspection:** Scrutinize the general documentation if available, even if the search fails. I might find it indexed under different terminology.\n",
            "\n",
            "**Actionable Insights:**\n",
            "\n",
            "1.  **Implement Iterative Refinement:** Modify the `search_docs` call in a loop. Start with a slightly improved query. If it fails, use the failure message to craft another, even more refined query. Limit the number of iterations to avoid infinite loops.\n",
            "\n",
            "    ```python\n",
            "    queries = [\"get user by ID\", \"retrieve user profile\", \"fetch user data\", \"search user\"] #Example. Update per API\n",
            "\n",
            "    for query in queries:\n",
            "        result = search_docs({'query': query})\n",
            "        if result['success'] and result['result'] != 'No documentation found for: ' + query:\n",
            "            print(f\"Found documentation with query: {query}\")\n",
            "            print(result['result'])\n",
            "            break #Stop on success\n",
            "        else:\n",
            "            print(f\"Query '{query}' failed.  Reason: {result['result']}\")\n",
            "\n",
            "    #If none of the queries work, consider further investigation\n",
            "    ```\n",
            "\n",
            "2.  **Prioritize API-Specific Terminology:** Actively look for and use the terminology employed in the target API's documentation. This might require initially skimming available documentation to identify key terms related to user management.\n",
            "\n",
            "3.  **Consider adding more context**: If this search is happening inside a bigger task, add what the bigger task is about as additional information to the search to further narrow down the search scope.\n",
            "\n",
            "By implementing these changes, I can significantly improve the chances of finding the relevant documentation and successfully completing the task of getting user information from the API. Remember to carefully analyze the API documentation and error messages to adapt these strategies to the specific characteristics of each API.\n",
            "\n",
            "💾 Stored reflection in memory for next attempt\n",
            "\n",
            "============================================================\n",
            "ATTEMPT 2/3\n",
            "============================================================\n",
            "\n",
            "📚 Consulting Memory:\n",
            "Past Attempt:\n",
            "Task: Calculate the result of 100 divided by 5\n",
            "What Failed: Code executed successfully. Result: None\n",
            "Lesson Learned: Success - approach worked well\n",
            "\n",
            "Past Attempt:\n",
            "Task: Get user information from the API\n",
            "What Failed: {'success': True, 'result': 'No documentation found for: get user information', 'error': None}\n",
            "Lesson Learned: Okay, let's break down how to improve this process based on the evaluation.\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  **What should be done differently next time?**\n",
            "\n",
            "*   **Refine the Search Query:** Instead of a broad \"get user information,\" try to be more specific based on what I *know* about the API. Does it have user IDs, usernames, email addresses? Try searches like:\n",
            "    *   `get user by ID`\n",
            "    *   `retrieve user profile`\n",
            "    *   `fetch user data`\n",
            "    *   `user authentication` (if it's about logging in or accessing user data)\n",
            "    *   `search user`\n",
            "\n",
            "*   **Check the API's Naming Conventions:** Is there a standard way the API names its functions and parameters related to users? If I've seen examples of other API calls, mimic that style. For example, if other functions use the prefix \"fetch,\" try \"fetch user.\"\n",
            "\n",
            "*   **Consider API Version:** If the API has versions, make sure I'm searching documentation for the correct version. Some functions might have changed or been deprecated.\n",
            "\n",
            "*   **Explore API Documentation Directly:** Before even using `search_docs`, if possible, explore a general documentation index or table of contents. This can give a sense of the overall structure and naming conventions used within the documentation.\n",
            "\n",
            "2.  **What specific mistakes to avoid?**\n",
            "\n",
            "*   **Using overly general queries:** Avoid phrasing questions in very broad terms that could relate to a wide range of concepts.\n",
            "*   **Assuming the documentation will use plain English:** API documentation is often quite technical and uses specific terminology.\n",
            "\n",
            "3.  **What strategy would work better?**\n",
            "\n",
            "*   **Iterative Search:** Start with a slightly more specific query than the original, and then refine further based on the results (or lack thereof). If the first refined search fails, try another refinement in a different direction.\n",
            "*   **Keyword Combination:** Combine keywords related to the action (e.g., \"get,\" \"retrieve,\" \"fetch\") with keywords related to the data (e.g., \"user,\" \"profile,\" \"account\").\n",
            "*   **Break Down the Goal:** If \"get user information\" is too broad, break it down into smaller pieces. E.g., first find documentation on *authenticating* a user, then documentation on *retrieving* their details.\n",
            "*   **Examine Successful Calls (If Available):** If other API calls have worked, look at the code or documentation related to those calls.  This might give clues as to how to structure the search for user information.\n",
            "*   **Look for Related Concepts:** If I can't find \"user information\" directly, search for related concepts, like \"authentication,\" \"authorization,\" \"profile,\" \"account.\"  The documentation for these might contain hints or links to the user information functions.\n",
            "*   **Document Inspection:** Scrutinize the general documentation if available, even if the search fails. I might find it indexed under different terminology.\n",
            "\n",
            "**Actionable Insights:**\n",
            "\n",
            "1.  **Implement Iterative Refinement:** Modify the `search_docs` call in a loop. Start with a slightly improved query. If it fails, use the failure message to craft another, even more refined query. Limit the number of iterations to avoid infinite loops.\n",
            "\n",
            "    ```python\n",
            "    queries = [\"get user by ID\", \"retrieve user profile\", \"fetch user data\", \"search user\"] #Example. Update per API\n",
            "\n",
            "    for query in queries:\n",
            "        result = search_docs({'query': query})\n",
            "        if result['success'] and result['result'] != 'No documentation found for: ' + query:\n",
            "            print(f\"Found documentation with query: {query}\")\n",
            "            print(result['result'])\n",
            "            break #Stop on success\n",
            "        else:\n",
            "            print(f\"Query '{query}' failed.  Reason: {result['result']}\")\n",
            "\n",
            "    #If none of the queries work, consider further investigation\n",
            "    ```\n",
            "\n",
            "2.  **Prioritize API-Specific Terminology:** Actively look for and use the terminology employed in the target API's documentation. This might require initially skimming available documentation to identify key terms related to user management.\n",
            "\n",
            "3.  **Consider adding more context**: If this search is happening inside a bigger task, add what the bigger task is about as additional information to the search to further narrow down the search scope.\n",
            "\n",
            "By implementing these changes, I can significantly improve the chances of finding the relevant documentation and successfully completing the task of getting user information from the API. Remember to carefully analyze the API documentation and error messages to adapt these strategies to the specific characteristics of each API.\n",
            "\n",
            "🧠 Plan:\n",
            "Tool: search_docs\n",
            "Params: {\"query\": \"get user by ID\"}\n",
            "Reasoning: Based on past experience, a more specific query like \"get user by ID\" is more likely to yield results than a general query like \"get user information\". This query assumes the API allows fetching user information based on a user ID.\n",
            "\n",
            "\n",
            "⚡ Executing: search_docs with {'query': 'get user by ID'}\n",
            "📊 Outcome: {'success': True, 'result': 'No documentation found for: get user by ID', 'error': None}\n",
            "\n",
            "🔍 Evaluation:\n",
            "1. No\n",
            "2. The search query \"get user by ID\" did not find any relevant documentation. This suggests either the documentation is missing, poorly indexed, or the query was too specific.\n",
            "3. N/A\n",
            "\n",
            "Evaluation: The task failed because the API documentation lookup did not find relevant information. The search query needs to be refined or the documentation needs to be updated/improved.\n",
            "\n",
            "💭 Reflection:\n",
            "Okay, let's reflect on how to improve the process of retrieving user information from the API based on the provided feedback.\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  **What should be done differently next time?**\n",
            "\n",
            "    *   **Broaden the initial search:** Instead of directly searching for \"get user by ID\", start with a more general query like \"user information API\" or \"get user data\".  This will help uncover relevant documentation even if the specific wording isn't a perfect match.\n",
            "    *   **Explore different keywords:** Consider alternative keywords related to user retrieval, such as \"retrieve user,\" \"fetch user,\" \"user lookup,\" \"user profile,\" \"user details,\" or \"user account.\"\n",
            "    *   **Check for parameter information:** After a broader search, If there is a documentation page returned, try to find information about what parameters can be used in API calls (e.g., is an ID required).\n",
            "    *   **Inspect the API documentation structure:** If there's a table of contents or a well-defined structure, browse the documentation manually to identify sections related to user management or data retrieval.\n",
            "    *   **Consider the API provider's terminology:**  Is the API using language that is different from what is being expected, e.g. 'customer' instead of 'user', 'member' instead of 'user', etc.\n",
            "\n",
            "2.  **What specific mistakes to avoid?**\n",
            "\n",
            "    *   **Relying solely on very specific queries in the first attempt:** This is clearly unproductive when documentation is missing or poorly indexed. Avoid being too narrow initially.\n",
            "    *   **Assuming a direct keyword match is required:** The API documentation might use different terminology.\n",
            "    *   **Not exploring alternative keywords:** Get creative with synonyms and related terms.\n",
            "    *   **Not trying a broader search after a failed specific search.**\n",
            "\n",
            "3.  **What strategy would work better?**\n",
            "\n",
            "    *   **Iterative Search Refinement:**\n",
            "        1.  **Start Broad:** Begin with a general query like \"user information API.\"\n",
            "        2.  **Analyze Results:** If the initial search returns documentation, scan the results quickly for sections related to user retrieval or management.\n",
            "        3.  **Refine Based on Results:** If the initial results aren't helpful, refine the query based on:\n",
            "            *   Keywords found in the documentation titles or descriptions.\n",
            "            *   Knowledge of common API design patterns.\n",
            "        4.  **Try different keywords:** Explore alternative keywords such as \"retrieve user,\" \"fetch user,\" \"user lookup,\" \"user profile,\" \"user details,\" or \"user account.\"\n",
            "        5.  **Inspect the API documentation structure:** If the initial results returned documentation, manually inspect the structure (table of contents) for relevant sections.\n",
            "        6.  **If the steps above all fail:** Consider that you may need to contact the API provider to determine how to access the proper documentation.\n",
            "\n",
            "**Actionable Insights:**\n",
            "\n",
            "*   **Implement an iterative search strategy.** Prioritize broader searches initially and refine based on the results.\n",
            "*   **Build a vocabulary list:** Keep a list of alternative keywords that might be relevant to user retrieval. This will help avoid getting stuck on a single term.\n",
            "*   **Consider common API conventions:** If familiar with REST principles or other API standards, think about how user retrieval endpoints are typically structured (e.g., `/users/{user_id}`).  This may suggest possible documentation sections.\n",
            "*   **When a more general documentation page is returned:** Check for parameter information.\n",
            "*   **Log failed queries and corresponding alternatives:** This helps track what approaches have been tried and provides a record for future reference.\n",
            "*   **If possible, give feedback on documentation quality:** If the documentation is missing or poorly indexed, report this to the API provider.  This improves the experience for everyone.\n",
            "\n",
            "By implementing these changes, the chances of successfully finding the correct API documentation and retrieving user information will significantly improve.\n",
            "\n",
            "💾 Stored reflection in memory for next attempt\n",
            "\n",
            "============================================================\n",
            "ATTEMPT 3/3\n",
            "============================================================\n",
            "\n",
            "📚 Consulting Memory:\n",
            "Past Attempt:\n",
            "Task: Calculate the result of 100 divided by 5\n",
            "What Failed: Code executed successfully. Result: None\n",
            "Lesson Learned: Success - approach worked well\n",
            "\n",
            "Past Attempt:\n",
            "Task: Get user information from the API\n",
            "What Failed: {'success': True, 'result': 'No documentation found for: get user information', 'error': None}\n",
            "Lesson Learned: Okay, let's break down how to improve this process based on the evaluation.\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  **What should be done differently next time?**\n",
            "\n",
            "*   **Refine the Search Query:** Instead of a broad \"get user information,\" try to be more specific based on what I *know* about the API. Does it have user IDs, usernames, email addresses? Try searches like:\n",
            "    *   `get user by ID`\n",
            "    *   `retrieve user profile`\n",
            "    *   `fetch user data`\n",
            "    *   `user authentication` (if it's about logging in or accessing user data)\n",
            "    *   `search user`\n",
            "\n",
            "*   **Check the API's Naming Conventions:** Is there a standard way the API names its functions and parameters related to users? If I've seen examples of other API calls, mimic that style. For example, if other functions use the prefix \"fetch,\" try \"fetch user.\"\n",
            "\n",
            "*   **Consider API Version:** If the API has versions, make sure I'm searching documentation for the correct version. Some functions might have changed or been deprecated.\n",
            "\n",
            "*   **Explore API Documentation Directly:** Before even using `search_docs`, if possible, explore a general documentation index or table of contents. This can give a sense of the overall structure and naming conventions used within the documentation.\n",
            "\n",
            "2.  **What specific mistakes to avoid?**\n",
            "\n",
            "*   **Using overly general queries:** Avoid phrasing questions in very broad terms that could relate to a wide range of concepts.\n",
            "*   **Assuming the documentation will use plain English:** API documentation is often quite technical and uses specific terminology.\n",
            "\n",
            "3.  **What strategy would work better?**\n",
            "\n",
            "*   **Iterative Search:** Start with a slightly more specific query than the original, and then refine further based on the results (or lack thereof). If the first refined search fails, try another refinement in a different direction.\n",
            "*   **Keyword Combination:** Combine keywords related to the action (e.g., \"get,\" \"retrieve,\" \"fetch\") with keywords related to the data (e.g., \"user,\" \"profile,\" \"account\").\n",
            "*   **Break Down the Goal:** If \"get user information\" is too broad, break it down into smaller pieces. E.g., first find documentation on *authenticating* a user, then documentation on *retrieving* their details.\n",
            "*   **Examine Successful Calls (If Available):** If other API calls have worked, look at the code or documentation related to those calls.  This might give clues as to how to structure the search for user information.\n",
            "*   **Look for Related Concepts:** If I can't find \"user information\" directly, search for related concepts, like \"authentication,\" \"authorization,\" \"profile,\" \"account.\"  The documentation for these might contain hints or links to the user information functions.\n",
            "*   **Document Inspection:** Scrutinize the general documentation if available, even if the search fails. I might find it indexed under different terminology.\n",
            "\n",
            "**Actionable Insights:**\n",
            "\n",
            "1.  **Implement Iterative Refinement:** Modify the `search_docs` call in a loop. Start with a slightly improved query. If it fails, use the failure message to craft another, even more refined query. Limit the number of iterations to avoid infinite loops.\n",
            "\n",
            "    ```python\n",
            "    queries = [\"get user by ID\", \"retrieve user profile\", \"fetch user data\", \"search user\"] #Example. Update per API\n",
            "\n",
            "    for query in queries:\n",
            "        result = search_docs({'query': query})\n",
            "        if result['success'] and result['result'] != 'No documentation found for: ' + query:\n",
            "            print(f\"Found documentation with query: {query}\")\n",
            "            print(result['result'])\n",
            "            break #Stop on success\n",
            "        else:\n",
            "            print(f\"Query '{query}' failed.  Reason: {result['result']}\")\n",
            "\n",
            "    #If none of the queries work, consider further investigation\n",
            "    ```\n",
            "\n",
            "2.  **Prioritize API-Specific Terminology:** Actively look for and use the terminology employed in the target API's documentation. This might require initially skimming available documentation to identify key terms related to user management.\n",
            "\n",
            "3.  **Consider adding more context**: If this search is happening inside a bigger task, add what the bigger task is about as additional information to the search to further narrow down the search scope.\n",
            "\n",
            "By implementing these changes, I can significantly improve the chances of finding the relevant documentation and successfully completing the task of getting user information from the API. Remember to carefully analyze the API documentation and error messages to adapt these strategies to the specific characteristics of each API.\n",
            "\n",
            "Past Attempt:\n",
            "Task: Get user information from the API\n",
            "What Failed: {'success': True, 'result': 'No documentation found for: get user by ID', 'error': None}\n",
            "Lesson Learned: Okay, let's reflect on how to improve the process of retrieving user information from the API based on the provided feedback.\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  **What should be done differently next time?**\n",
            "\n",
            "    *   **Broaden the initial search:** Instead of directly searching for \"get user by ID\", start with a more general query like \"user information API\" or \"get user data\".  This will help uncover relevant documentation even if the specific wording isn't a perfect match.\n",
            "    *   **Explore different keywords:** Consider alternative keywords related to user retrieval, such as \"retrieve user,\" \"fetch user,\" \"user lookup,\" \"user profile,\" \"user details,\" or \"user account.\"\n",
            "    *   **Check for parameter information:** After a broader search, If there is a documentation page returned, try to find information about what parameters can be used in API calls (e.g., is an ID required).\n",
            "    *   **Inspect the API documentation structure:** If there's a table of contents or a well-defined structure, browse the documentation manually to identify sections related to user management or data retrieval.\n",
            "    *   **Consider the API provider's terminology:**  Is the API using language that is different from what is being expected, e.g. 'customer' instead of 'user', 'member' instead of 'user', etc.\n",
            "\n",
            "2.  **What specific mistakes to avoid?**\n",
            "\n",
            "    *   **Relying solely on very specific queries in the first attempt:** This is clearly unproductive when documentation is missing or poorly indexed. Avoid being too narrow initially.\n",
            "    *   **Assuming a direct keyword match is required:** The API documentation might use different terminology.\n",
            "    *   **Not exploring alternative keywords:** Get creative with synonyms and related terms.\n",
            "    *   **Not trying a broader search after a failed specific search.**\n",
            "\n",
            "3.  **What strategy would work better?**\n",
            "\n",
            "    *   **Iterative Search Refinement:**\n",
            "        1.  **Start Broad:** Begin with a general query like \"user information API.\"\n",
            "        2.  **Analyze Results:** If the initial search returns documentation, scan the results quickly for sections related to user retrieval or management.\n",
            "        3.  **Refine Based on Results:** If the initial results aren't helpful, refine the query based on:\n",
            "            *   Keywords found in the documentation titles or descriptions.\n",
            "            *   Knowledge of common API design patterns.\n",
            "        4.  **Try different keywords:** Explore alternative keywords such as \"retrieve user,\" \"fetch user,\" \"user lookup,\" \"user profile,\" \"user details,\" or \"user account.\"\n",
            "        5.  **Inspect the API documentation structure:** If the initial results returned documentation, manually inspect the structure (table of contents) for relevant sections.\n",
            "        6.  **If the steps above all fail:** Consider that you may need to contact the API provider to determine how to access the proper documentation.\n",
            "\n",
            "**Actionable Insights:**\n",
            "\n",
            "*   **Implement an iterative search strategy.** Prioritize broader searches initially and refine based on the results.\n",
            "*   **Build a vocabulary list:** Keep a list of alternative keywords that might be relevant to user retrieval. This will help avoid getting stuck on a single term.\n",
            "*   **Consider common API conventions:** If familiar with REST principles or other API standards, think about how user retrieval endpoints are typically structured (e.g., `/users/{user_id}`).  This may suggest possible documentation sections.\n",
            "*   **When a more general documentation page is returned:** Check for parameter information.\n",
            "*   **Log failed queries and corresponding alternatives:** This helps track what approaches have been tried and provides a record for future reference.\n",
            "*   **If possible, give feedback on documentation quality:** If the documentation is missing or poorly indexed, report this to the API provider.  This improves the experience for everyone.\n",
            "\n",
            "By implementing these changes, the chances of successfully finding the correct API documentation and retrieving user information will significantly improve.\n",
            "\n",
            "🧠 Plan:\n",
            "Tool: search_docs\n",
            "Params: {\"query\": \"user information API\"}\n",
            "Reasoning: Based on previous failures, I'm starting with a broader search term to identify general documentation related to user information within the API. This will allow me to explore the available resources and identify more specific keywords or sections relevant to retrieving user data. This is in line with the iterative refinement strategy.\n",
            "\n",
            "\n",
            "⚡ Executing: search_docs with {'query': 'user information API'}\n",
            "📊 Outcome: {'success': True, 'result': 'APIs allow communication between applications.', 'error': None}\n",
            "\n",
            "🔍 Evaluation:\n",
            "1. No\n",
            "2. The search query \"user information API\" likely returned a very general result about APIs rather than specific documentation on how to retrieve user information from a particular API. It didn't find the relevant documentation needed.\n",
            "3. N/A\n",
            "\n",
            "Evaluation: The search query was too generic. A more specific query, including the name of the API or the specific action (e.g., \"get user endpoint\"), would be more effective.\n",
            "\n",
            "💭 Reflection:\n",
            "Okay, here's a reflection on the experience, focusing on actionable insights:\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  **What should be done differently next time?**\n",
            "\n",
            "    *   **More Specific Query:** Next time, I need to craft a more targeted search query. This means considering the specific API I am targeting (if known) or thinking about the specific endpoint or action required to retrieve user information. I should also consider including terms like \"endpoint,\" \"request,\" \"response,\" \"documentation,\" or \"API reference.\"  I should also iterate, trying different phrasings. If the first query is too broad, immediately refine it.\n",
            "\n",
            "2.  **What specific mistakes to avoid?**\n",
            "\n",
            "    *   **Generic Queries:** Avoid using overly broad search terms like \"user information API\" without specifying the API or action. This is highly likely to return general information about APIs instead of the required documentation.\n",
            "    *   **Assuming the First Result is Correct:** Don't assume the first search result is the most relevant.  Evaluate the result critically to see if it truly addresses the task.\n",
            "    *   **Not Iterating Quickly:** Don't get stuck on a single, ineffective query. Be prepared to modify the search term and try again quickly.\n",
            "\n",
            "3.  **What strategy would work better?**\n",
            "\n",
            "    *   **API-Specific Search:**  If the API name is known, use it:  `search_docs({'query': 'API_NAME get user endpoint'})` or `search_docs({'query': 'API_NAME user API documentation'})`.  Replace `API_NAME` with the actual name.\n",
            "    *   **Endpoint-Focused Search:** If you know you need to access an \"endpoint,\" use that keyword: `search_docs({'query': 'user information endpoint API'})` or `search_docs({'query': 'get user details API endpoint'})`.\n",
            "    *   **Documentation-Oriented Search:** Target the documentation directly: `search_docs({'query': 'API_NAME user API documentation'})` or `search_docs({'query': 'API_NAME API reference user'})`.\n",
            "    *   **Action-Verb Search:** Use action verbs to clarify the intent: `search_docs({'query': 'API_NAME API how to retrieve user information'})` or `search_docs({'query': 'API_NAME get user profile API'})`.\n",
            "    *   **Error Message Integration:** If there's a previous error message, or a known data structure related to users in the API, incorporate elements of those into the search. This could improve relevance dramatically.\n",
            "    *   **Progressive Refinement:** Start with a slightly more specific query than the previous one, analyze the result, and refine again. This iterative process is crucial. For example:\n",
            "        1.  `search_docs({'query': 'user information API'})`\n",
            "        2.  (Analyze result, deemed too general)\n",
            "        3.  `search_docs({'query': 'get user information API endpoint'})`\n",
            "        4.  (Analyze result, might be slightly better, but still not ideal)\n",
            "        5.  `search_docs({'query': 'API_NAME get user details API endpoint'})` (If API name is known)\n",
            "\n",
            "**Actionable Insights:**\n",
            "\n",
            "1.  **Prioritize API Name:** If the API name is available, *always* include it in the search query. This drastically narrows the scope and increases the chances of finding relevant documentation.\n",
            "\n",
            "2.  **Use Specific Keywords:**  Favor keywords like \"endpoint,\" \"API reference,\" \"documentation,\" \"get,\" \"retrieve,\" \"request,\" and \"response\" over generic terms like \"information.\"\n",
            "\n",
            "3.  **Embrace Iteration:** Treat search queries as experiments.  Analyze the results, identify shortcomings, and refine the query accordingly.  Don't be afraid to try several different queries to find the best one.\n",
            "\n",
            "4.  **Learn from Failure:** Record the failed query and why it failed. This helps to build a knowledge base of ineffective search strategies.\n",
            "\n",
            "5.  **Implement a \"Specificity Scale\":** Before running a search, mentally rate the specificity of the query.  If it's rated low, immediately try to add more specific terms.  Aim for a \"medium-high\" specificity rating to start.\n",
            "\n",
            "By following these insights, I can significantly improve my ability to retrieve the necessary information from the API documentation.\n",
            "\n",
            "💾 Stored reflection in memory for next attempt\n",
            "\n",
            "❌ Task failed after 3 attempts\n",
            "\n",
            "\n",
            "============================================================\n",
            "EPISODIC MEMORY (What the agent learned)\n",
            "============================================================\n",
            "\n",
            "Memory 1:\n",
            "Task: Calculate the result of 100 divided by 5\n",
            "Attempt: 1\n",
            "Reflection: Success - approach worked well...\n",
            "\n",
            "Memory 2:\n",
            "Task: Get user information from the API\n",
            "Attempt: 1\n",
            "Reflection: Okay, let's break down how to improve this process based on the evaluation.\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  **...\n",
            "\n",
            "Memory 3:\n",
            "Task: Get user information from the API\n",
            "Attempt: 2\n",
            "Reflection: Okay, let's reflect on how to improve the process of retrieving user information from the API based ...\n",
            "\n",
            "Memory 4:\n",
            "Task: Get user information from the API\n",
            "Attempt: 3\n",
            "Reflection: Okay, here's a reflection on the experience, focusing on actionable insights:\n",
            "\n",
            "**Reflection:**\n",
            "\n",
            "1.  ...\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "Hxc72SpwUjqC"
      },
      "execution_count": null,
      "outputs": []
    }
  ]
}